import { WebviewWindow } from "@tauri-apps/api/webviewWindow";

// 窗口池 - 用于复用窗口实例
const windowPool = new Map();

const appName = '阿瑞斯仿微信Tauri'

// 窗口配置优化函数
const optimizeWindowConfig = (config) => {
  return {
    ...config,
    // 设置默认值
    width: config.width || 800,
    height: config.height || 600,
    resizable: config.resizable ?? true,
    maximizable: config.maximizable ?? true,
    minimizable: config.minimizable ?? true,
    closable: config.closable ?? true,
    center: config.center ?? true,
  };
};

export const useCreateWindow = () => {
  return {
    /**
     * @desc: 常规的创建窗口【性能一般，方便使用】
     * @params:{
     *   route: 路由名称，用于创建窗口，如'/chat'，其实是openWindow配置项里的label，需要保证唯一，如果需要创建多个窗口，请使用不同的路由名称
     * }
     * @author: yanrui
     * @time: 2025-10-28 11:50:08
     */
    async openWindow(route, config) {
      console.log('config', config)
      const win = new WebviewWindow(route, optimizeWindowConfig({
        ...config,
        title: config.title || appName,
        url: config?.url || `/${route}`,
      }));
      await win.once("tauri://created", async () => {
        console.log(`${route}窗口创建成功`);
      });
      await win.once("tauri://error", async function (e) {
        // 如果窗口已存在，则聚焦显示，如果是最小化状态，则取消最小化，都是细节呀
        // 暂时先用关键词判断是否存在，以后再查查对应的错误码
        if(e.payload && e.payload.includes('already exists')) {
          if(await win.isMinimized()) {
            await win.unminimize();
          } else {
            await win.setFocus()
          }
        }
        console.log(`${route}窗口创建失败：`, e);
      });
    },

    // 创建窗口，失去焦点时、窗口自动关闭；
    async openBlurWindow(route, config) {
      const win = new WebviewWindow(route, optimizeWindowConfig({
        ...config,
        title: config.title || appName,
        url: config?.url || `/${route}`,
      }));
      win.once("tauri://created", async () => {
        console.log(`${route}窗口创建成功`);

        // 获取子窗口实例
        const childWindow = await WebviewWindow.getByLabel(route)

        // 监听该子窗口的焦点变化
        const unlisten = await childWindow.onFocusChanged(async ({ payload: focused }) => {
          if (!focused) {
            console.log('子窗口失去焦点，准备关闭')
            win.close()
            unlisten() // 取消监听
          }
        })

      });
      win.once("tauri://error", function (e) {
        console.log(`${route}窗口创建失败：`, e);
      });
    },


    // 设置窗口位置
    async setWindowPosition(route, x, y) {
      try {
        const win = await WebviewWindow.getByLabel(route);
        if (win) {
          await win.setPosition({ x, y });
          return true;
        }
        return false;
      } catch (error) {
        console.error(`设置窗口${route}位置失败:`, error);
        return false;
      }
    },

    // 设置窗口显示/隐藏
    async setWindowVisibility(route, visible) {
      try {
        const win = await WebviewWindow.getByLabel(route);
        if (win) {
          if (visible) {
            await win.show();
          } else {
            await win.hide();
          }
          return true;
        }
      } catch (error) {
        console.error(`设置窗口${route}可见性失败:`, error);
        return false;
      }
    },

    // 设置窗口显示/隐藏，任务栏显示/隐藏
    async setWindowVisibilityAndTaskbar(route, visible) {
      try {
        const win = await WebviewWindow.getByLabel(route);
        if (win) {
          if (visible) {
            // 如果是最小化状态，则直接取消最小化，否则就显示窗口和任务栏(并且设置聚焦，有时会在其他窗口下面)
            if(await win.isMinimized()) {
              await win.unminimize();
            } else {
              await win.show();
              await win.setFocus()
              await win.setSkipTaskbar(false);
            }
          } else {
            await win.hide();
            await win.setSkipTaskbar(true);
          }
          return true;
        }
      } catch (error) {
        console.error(`设置窗口${route}可见性和任务栏显示失败:`, error);
        return false;
      }
    },

    // 检查窗口是否存在
    async isWindowExists(route) {
      try {
        const win = await WebviewWindow.getByLabel(route);
        return !!win;
      } catch (error) {
        return false;
      }
    },

    // 获取窗口状态
    async getWindowStatus(route) {
      try {
        const win = await WebviewWindow.getByLabel(route);
        if (win) {
          const isVisible = await win.isVisible();
          const position = await win.position();
          const size = await win.size();
          return { exists: true, visible: isVisible, position, size };
        }
        return { exists: false };
      } catch (error) {
        console.error(`获取窗口${route}状态失败:`, error);
        return { exists: false, error: error.message };
      }
    },

    // 返回该窗口的实例
    async getWindowByRoute(route) {
      return await WebviewWindow.getByLabel(route);
    },

    // 关闭当前窗口
    async closeCurrentWindow() {
      await WebviewWindow.getCurrent().close();
    },

    // 关闭(销毁)目标窗口
    async destroyWindow(route) {
      const win = await WebviewWindow.getByLabel(route);
      if (win) {
        await win.close();
      }
    },

    // 退出登录，只保留登录窗口、tray窗口，销毁其他所有窗口
    async destroyOtherWindows() {
      try {
        // 获取所有窗口
        const allWindows = await WebviewWindow.getAll();

        // 遍历并销毁除登录和托盘窗口外的所有窗口
        for (const window of allWindows) {
          const label = window.label;
          // 保留登录窗口和托盘窗口，销毁其他窗口
          if (label !== 'login' && label !== 'tray') {
            try {
              // 先隐藏再关闭，确保窗口被正确销毁
              await window.hide().catch((e) => {
                console.error(`隐藏窗口 ${label} 失败:`, e);
              });
              await window.close().catch((e) => {
                console.error(`关闭窗口 ${label} 失败:`, e);
              });
              console.log(`窗口 ${label} 已销毁`);
            } catch (error) {
              console.error(`销毁窗口 ${label} 失败:`, error);
            }
          }
        }

        return true;
      } catch (error) {
        console.error('销毁窗口时发生错误:', error);
        return false;
      }
    },

    // 设置当前窗口显示、并聚焦，用于减少白屏问题，需要配合在创建窗口时设置 visible: false, focus: false,
    async setCurrentWindowShowAndFocus() {
      const win = await WebviewWindow.getCurrent();
      await win.show();
      await win.setFocus();
    }
  }
};
